package com.tbsoft.ehr.dao;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.List;

import org.hibernate.HibernateException;
import org.springframework.dao.InvalidDataAccessResourceUsageException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.tbsoft.ehr.model.AttachFile;
import com.tbsoft.ehr.model.BaseEntity;
import com.tbsoft.ehr.util.ConfigProps;
import com.tbsoft.ehr.util.FileUtils;

/**
 * Contains common behaviour to all hibernate factories
 * 
 */
public abstract class BaseDaoImpl<T extends BaseEntity> extends
		HibernateDaoSupport implements BaseDao<T> {
	private String tmpAttachPath = (String) ConfigProps.getContextProperty("attach.file.path")+File.separator+"tmp";
	private String storeAttachPath = (String) ConfigProps.getContextProperty("attach.file.path")+File.separator+"store";

	/**
     * 
     */
	public BaseDaoImpl() {
		super();
	}

	/**
	 * insert a new entity. create- and lastmodified-date is set with current
	 * time.
	 * 
	 * @param entity
	 *            - detached entity object
	 */
	@SuppressWarnings("unchecked")
	public T save(T entity) {
		if (null == entity) {
			throw new InvalidDataAccessResourceUsageException(
					"entity must not be null");
		}
		try {
			getHibernateTemplate().save(entity);
			return entity;
		} catch (HibernateException ex) {
			logger
					.debug(
							"save: caught HibernateException, call to convertHibernateException",
							ex);
			throw convertHibernateAccessException(ex);
		}
	}

	/**
	 * inserts a new detached entity or updates if it already exists. create-
	 * and update-date are set automatically.
	 * 
	 * @param entity
	 *            - entity object to be inserted or updated
	 */
	public T saveOrUpdate(T entity) {
		if (null == entity) {
			throw new InvalidDataAccessResourceUsageException(
					"entity must not be null");
		}

		try {
			getHibernateTemplate().saveOrUpdate(entity);
			return entity;
		} catch (HibernateException ex) {
			logger
					.debug(
							"saveOrUpdate: caught HibernateException, call to convertHibernateException",
							ex);
			throw convertHibernateAccessException(ex);
		}
	}
	/**
	 * @desc 逻辑删除
	 */
	public void logicDelete(Class<? extends BaseEntity> entityClass,Serializable id ){
		BaseEntity entity = (BaseEntity) getHibernateTemplate().get(entityClass, id);
		entity.setStatus("D");
		getHibernateTemplate().update(entity);	
	}
	public void delete(T entity) {
		if (null == entity) {
			throw new InvalidDataAccessResourceUsageException(
					"entity must not be null");
		}
		try {
			getHibernateTemplate().delete(entity);
		} catch (HibernateException ex) {
			logger
					.debug(
							"delete: caught HibernateException, call to convertHibernateException",
							ex);
			throw convertHibernateAccessException(ex);
		}
	}	

	@SuppressWarnings("unchecked")
	public T merge(T entity) {
		if (null == entity) {
			throw new InvalidDataAccessResourceUsageException(
					"entity must not be null");
		}
		try {
			return (T) getHibernateTemplate().merge(entity);
		} catch (HibernateException ex) {
			logger
					.debug(
							"merge: caught HibernateException, call to convertHibernateException",
							ex);
			throw convertHibernateAccessException(ex);
		}
	}

	/**
	 * 保存对象列表
	 * 
	 * @param items
	 * @return
	 * @throws Exception
	 */
	public boolean saveList(List<T> items) {
		int count = 1;
		for (Object item : items) {
			getHibernateTemplate().save(item);
			// 分批提交
			if (count % 20 == 0) {
				getHibernateTemplate().flush();
				getHibernateTemplate().clear();
			}
			count++;
		}
		return true;
	}

	/**
	 * 保存对象列表
	 * 
	 * @param items
	 * @return
	 * @throws Exception
	 */
	public boolean saveOrUpdateList(List<T> items) {
		int count = 1;
		for (Object item : items) {
			getHibernateTemplate().saveOrUpdate(item);
			// 分批保存
			if (count % 20 == 0) {
				getHibernateTemplate().flush();
				getHibernateTemplate().clear();
			}
			count++;
		}
		return true;
	}
	@Override
	public void saveOrUpdateAttachfile(List<AttachFile> attachFileList, String businessId) throws IOException {
		File storeFilePath = new File(storeAttachPath);
		if(!storeFilePath.exists()||!storeFilePath.isDirectory()){
			storeFilePath.mkdirs();
		}
		for(AttachFile af:attachFileList){
			af.setBussinessId(businessId);
			File tmpFile=new File(tmpAttachPath+File.separator+af.getAttachFileId());
			if(tmpFile.exists()){
				FileUtils.copyFile(tmpFile, new File(storeAttachPath+File.separator+af.getAttachFileId()));
				tmpFile.delete();
			}
			getHibernateTemplate().saveOrUpdate(af);
		}
	}
}
